using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Linq;

namespace CincinnatiLibraryCheckAvailability
{
    public enum Status
    {
        NewRelease,
        Default,
        OnHold,
        ReadyForPickup,
        CheckedOutToMe,
    }

    public static class Util
    {
        private static Dictionary<Status, string> _sdic;

        static Util()
        {
            _sdic = new Dictionary<Status, string>(5);
            _sdic.Add(Status.NewRelease, "New Release");
            _sdic.Add(Status.Default, "Default");
            _sdic.Add(Status.OnHold, "On Hold");
            _sdic.Add(Status.ReadyForPickup, "Ready for Pickup");
            _sdic.Add(Status.CheckedOutToMe, "Checked Out to Me");
        }

        public static string AsString(this Status s)
        {
            return _sdic[s];
        }

        public static bool IsSpecialStatus(this string s)
        {
            return _sdic.ContainsValue(s);
        }

        public static Status ToStatusEnum(this string s)
        {
            if (s.IsSpecialStatus())
                return _sdic.First(kv => kv.Value == s).Key;
            else return Status.Default;
        }
    }

    [Serializable]
    public class LibraryItem
    {
        private string url;
        private string title = "";
        private Status status = Status.NewRelease;
        private bool triggersEmail = false;
        private bool triggersIM = false;
        private Dictionary<Library, ItemStatus> statusAt;
        private int rank = -1;
        private bool putOnHold = false;
        private string inList = "Default";

        public string InList
        {
            get { return inList; }
            set { inList = value; }
        }

        public bool PutOnHold
        {
            get { return putOnHold; }
            set { putOnHold = value; }
        }

        public int Rank
        {
            get { return rank; }
            set { rank = value; }
        }
        
        public LibraryItem(string url)
        {
            this.url = url;
            statusAt = new Dictionary<Library,ItemStatus>();
        }

        public LibraryItem(SerializationInfo info, StreamingContext ctxt)
        {
            url = (string)info.GetValue("URL", typeof(string));
            title = (string)info.GetValue("Title", typeof(string));
            statusAt = (Dictionary<Library,ItemStatus>)info.GetValue("StatusAt", typeof(Dictionary<Library,ItemStatus>));
            triggersEmail = info.GetBoolean("triggersEmail");
            triggersIM = info.GetBoolean("triggersIM");
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            //You can use any custom name for your name-value pair. But make sure you
            // read the values with the same name. For ex:- If you write EmpId as "EmployeeId"
            // then you should read the same with "EmployeeId"
            info.AddValue("URL", url);
            info.AddValue("Title", title);
            info.AddValue("StatusAt", statusAt);
            info.AddValue("triggersEmail", triggersEmail);
            info.AddValue("triggersIM", triggersIM);
        }

        public override int GetHashCode()
        {
            return url.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(LibraryItem))
                return false;
            return ((LibraryItem)obj).url==this.url;
        }

        public override string ToString()
        {
            if (title == null || title.Length == 0)
                return url;
            else
            {
                if (IsNewRelease)
                    return title + " (New Release)";
                else return title;
            }
        }

        public string URL
        {
            get { return url; }
        }
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        public bool IsNewRelease
        {
            get { return status == Status.NewRelease; }
            set
            {
                if (status == Status.NewRelease || status == Status.Default)
                    status = value ? Status.NewRelease : Status.Default;
            }
        }
        public Status Status
        {
            get
            {
                if (string.IsNullOrEmpty(title))
                    return Status.Default;
                else return status;
            }
            set { status = value; }
        }
        public bool TriggersEmail
        {
            get { return triggersEmail; }
            set { triggersEmail = value; }
        }
        public bool TriggersIM
        {
            get { return triggersIM; }
            set { triggersIM = value; }
        }
        public Dictionary<Library, ItemStatus> StatusAt
        {
            get { return statusAt; }
        }
        public bool IsAtInterestedLibrary
        {
            get
            {
                foreach(Library l in statusAt.Keys)
                {
                    if(l.IsMonitored)
                        return true;
                }
                return false;
            }
        }
    }
}
